﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CrossLayerCommunication.WebService
{
    public delegate void NoMapping(IMessage messageNoMapped);

    public static class WebServiceResponseMapper
    {
        public static event NoMapping NoMapping;

        internal static void OnNoMapping(IMessage messagenomapped)
        {
            NoMapping handler = NoMapping;
            if (handler != null)
                handler(messagenomapped);
        }
    }

    public sealed class WebServiceResponseMapper<T>
    {
        private readonly Dictionary<IMessage, T> MessageResponseMapper = new Dictionary<IMessage, T>();
        private readonly T OkResponse;
        private readonly T UnknownResponse;

        public WebServiceResponseMapper(T okResponse, T unknownResponse)
        {
            OkResponse = okResponse;
            UnknownResponse = unknownResponse;
        }

        public WebServiceResponseMapper<T> AddMapping(T result, params IMessage[] messages)
        {
            foreach (IMessage message in messages)
            {
                if (MessageResponseMapper.ContainsKey(message))
                    throw new MappingAlreadyExistsException(message, MessageResponseMapper[message]);

                MessageResponseMapper.Add(message, result);
            }

            return this;
        }

        public T GetResponse(IOperationResult operationResult)
        {
            if (operationResult.WasSuccessful)
                return OkResponse;

            IMessage messageMapped = operationResult.Messages
                .First(item => MessageResponseMapper.ContainsKey(item));

            if (messageMapped == null)
                return MessageResponseMapper[messageMapped];

            foreach (IMessage message in operationResult.Messages)
                WebServiceResponseMapper.OnNoMapping(message);

            return UnknownResponse;
        }
    }
}
